package org.jbrisk.tests;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;

public class JBriskTestRunner extends BlockJUnit4ClassRunner {

	public JBriskTestRunner(Class<?> clazz) throws InitializationError {

		super(clazz);
	}

	@Override
	protected List<FrameworkMethod> computeTestMethods() {

		List<FrameworkMethod> testMethods = super.computeTestMethods();

		List<FrameworkMethod> allMethods = new ArrayList<FrameworkMethod>(testMethods.size());
		allMethods.addAll(testMethods);

		List<FrameworkMethod> testCaseMethods = getTestClass().getAnnotatedMethods(ParamTest.class);

		// Now multiplies the list of methods with the testCase annotation for
		// each value supplied
		for (FrameworkMethod method : testCaseMethods) {

			// Reatrieves TestCase annotation
			ParamTest testCases = method.getAnnotation(ParamTest.class);

			// Now for each value creates a FrameworkMethod
			Values[] values = testCases.value();

			for (Values value : values) {

				ParameterizedFrameworkMethod paramMethod = new ParameterizedFrameworkMethod(method.getMethod(), value.value());

				allMethods.add(paramMethod);
			}
		}
		
		Collections.sort(allMethods, new Comparator<FrameworkMethod>() {
		
			@Override
			public int compare(FrameworkMethod o1, FrameworkMethod o2) {

				return o1.getName().compareTo(o2.getName());
			}
		});

		return allMethods;
	}

	@Override
	protected Statement methodInvoker(FrameworkMethod method, Object test) {

		if (method instanceof ParameterizedFrameworkMethod) {

			return new ParameterizedInvokeMethod((ParameterizedFrameworkMethod)method, test);
			
		} else {
			
			// TODO Auto-generated method stub
			return super.methodInvoker(method, test);
		}
	}
}
